package com.yanyuan.snio.part;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * @author: yanyuan
 * @Date: 2021/3/17 11:22
 * @Description:
 * 一、使用NIO完成网络通信的三个核心
 * 1.通道（Channel）:负责连接
 *      java.nio.channels.channel接口
 *      --SelectableChannel
 *      -- SocketChannel
 *      --ServerSocketChannel
 *      --DatagramChannel
 *
 *      -- Pipe.SinkChannel
 *      -- Pipe.SourceChannel
 * 2.缓存区（Buffer）:负责数据的存储
 * 3.选择器（selector）：是selectableChannel的多路复用器，用于监控SelectableChannel的IO状况
 *
 */
public class NioP9Block {

    public void client() throws IOException {
        //1.获取通道
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));

        FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
        //2.分配指定大小的缓存区
        ByteBuffer buf = ByteBuffer.allocate(1024);
        //3.读取本地文件并发送到服务端
        while (inChannel.read(buf)  != -1){
            buf.flip();
            socketChannel.write(buf);
            buf.clear();
        }
        //关闭通道
        inChannel.close();
        socketChannel.close();
    }

    public void server() throws IOException {
        //1.获取通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        FileChannel outChannel = FileChannel.open(Paths.get("1copy.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE_NEW);
        //2.绑定连接
        serverSocketChannel.bind(new InetSocketAddress(9898));
        //3.获取客户端连接
        SocketChannel socketChannel = serverSocketChannel.accept();

        //4.分配指定大小缓存区
        ByteBuffer buf = ByteBuffer.allocate(1024);

        //5.接收客户端数据，并保存到本地
        while (socketChannel.read(buf) != -1){
            buf.flip();
            outChannel.write(buf);
            buf.clear();
        }

        //6.关闭通道
        socketChannel.close();
        serverSocketChannel.close();
    }
}
